#include "stdafx.h"
#include "..\Infraestruturex\tenta_reduzir.h"
using namespace System;
using namespace System::Text;
using namespace System::Collections::Generic;
using namespace	Microsoft::VisualStudio::TestTools::UnitTesting;

char proxAcao();
char* proxParam();

namespace Testes
{
	[TestClass]
	public ref class TentaReduzirTest
	{
	private:
		TestContext^ testContextInstance;

	public: 
		/// <summary>
		///Gets or sets the test context which provides
		///information about and functionality for the current test run.
		///</summary>
		property Microsoft::VisualStudio::TestTools::UnitTesting::TestContext^ TestContext
		{
			Microsoft::VisualStudio::TestTools::UnitTesting::TestContext^ get()
			{
				return testContextInstance;
			}
			System::Void set(Microsoft::VisualStudio::TestTools::UnitTesting::TestContext^ value)
			{
				testContextInstance = value;
			}
		};

		#pragma region Additional test attributes
		//
		//You can use the following additional attributes as you write your tests:
		//
		//Use ClassInitialize to run code before running the first test in the class
		//[ClassInitialize()]
		//static void MyClassInitialize(TestContext^ testContext) {};
		//
		//Use ClassCleanup to run code after all tests in a class have run
		//[ClassCleanup()]
		//static void MyClassCleanup() {};
		//
		//Use TestInitialize to run code before running each test
		//[TestInitialize()]
		//void MyTestInitialize() {};
		//
		//Use TestCleanup to run code after each test has run
		//[TestCleanup()]
		//void MyTestCleanup() {};
		//
#pragma endregion 

		[TestMethod]
		void Test_proxAcao()
		{
			novo_escopo();
			entra('S');
			entra('I');
			entra('K');
			Assert::AreEqual('S', proxAcao());
		};

		[TestMethod]
		void Test_proxAcao2()
		{
			novo_escopo();
			entra('S');
			entra('I');
			entra('K');
			Assert::AreEqual('S', proxAcao());
			Assert::AreEqual(0, strcmp("I", proxParam()));
		};

		[TestMethod]
		void Test_proxAcao3()
		{
			novo_escopo();
			entra('S');
			entra('(');
			entra('I');
			entra('K');
			entra(')');
			entra('I');
			Assert::AreEqual('S', proxAcao());
			Assert::AreEqual(0, strcmp("(IK)", proxParam()));
		};

		[TestMethod]
		void Test_proxAcao4()
		{
			novo_escopo();
			entra('S');
			entra('(');
			entra('I');
			entra('K');
			entra(')');
			entra('I');
			entra('K');
			Assert::AreEqual('S', proxAcao());
			Assert::AreEqual(0, strcmp("(IK)", proxParam()));
		};

		[TestMethod]
		void Test_proxAcao5()
		{
			novo_escopo();
			entra_string("S(I(SK)I)K");
			/*entra('S');
			entra('(');
			entra('I');
			entra('(');
			entra('S');
			entra('K');
			entra(')');
			entra('I');
			entra(')');
			entra('K');*/
			Assert::AreEqual('S', proxAcao());
			Assert::AreEqual(0, strcmp("(I(SK)I)", proxParam()));
		};

		[TestMethod]
		void Test_tenta_reduzir()
		{
			novo_escopo();
			entra_string("SIII");
			tenta_reduzir();
			Assert::AreEqual(0, strcmp("I", fila_atual()));
		};

		[TestMethod]
		void Test_tenta_reduzir2()
		{
			novo_escopo();
			entra('I');
			tenta_reduzir();
			novo_escopo();
			entra('K');tenta_reduzir();
			entra('K');tenta_reduzir();
			entra('I');tenta_reduzir();
			fecha_escopo();tenta_reduzir();
			novo_escopo();
			entra('I');tenta_reduzir();
			entra('I');tenta_reduzir();
			entra('K');tenta_reduzir();
			entra('S');tenta_reduzir();
			entra('I');tenta_reduzir();
			fecha_escopo();tenta_reduzir();

			Assert::AreEqual(0, strcmp("K(S)", fila_atual()));
		};

		void entra_reduz(char c) {
			entra(c);
			tenta_reduzir();
		}
		[TestMethod]
		void Test_tenta_reduzir3()
		{
			novo_escopo();
			entra_reduz('S');
			novo_escopo();
			entra_reduz('K');
			novo_escopo();
			entra_reduz('S');
			entra_reduz('I');
			fecha_escopo(); tenta_reduzir();
			fecha_escopo(); tenta_reduzir();
			novo_escopo();
			entra_reduz('S');
			novo_escopo();
			entra_reduz('K');
			entra_reduz('K');
			fecha_escopo(); tenta_reduzir();
			entra_reduz('I');
			fecha_escopo();tenta_reduzir();

			Assert::AreEqual(0, strcmp("S(K(SI))(S(KK)I)", fila_atual()));
		};

		[TestMethod]
		void Test_tenta_reduzir4()
		{
			novo_escopo();
			entra_reduz('S');
			entra_reduz('K');
			entra_reduz('K');
			novo_escopo();
			entra_reduz('S');
			entra_reduz('I');
			fecha_escopo();tenta_reduzir();
			novo_escopo();
			entra_reduz('S');
			entra_reduz('K');
			fecha_escopo();tenta_reduzir();

			Assert::AreEqual(0, strcmp("SI(SK)", fila_atual()));
		};
	};
}